//! Copyright 2012 NTH Technology, Inc.
//! All rights reserved
//!
#include "stm32f10x.h"
#include "BoardHardware.h"
#include "Config.h"
#include "Capture.h"
#include "pc.h"


extern "C"  {
    volatile U16  s_TxCounter = 0;
    volatile U16  s_TxLength = 0;
    volatile bool s_TxSendingFlag = false;
    volatile U8   s_pTxBuffer[2000];

    /*******************************************************************************
    Function name: USART1_IRQHandler
    Description: This function handles USART1 global interrupt request.
    Input: None
    Output: None
    *******************************************************************************/
    void USART1_IRQHandler(void)
    {
        uint8_t data;

        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
        {
            /* Read one byte from the receive data register */
            data = USART_ReceiveData(USART1);

//             USART3_ResetTimeout();
// 
//             if (USART3_RxCounter >= SIM900_RX_BUFF_LEN)
//             {
//                 USART3_RxCounter=0;
//             }
//             USART3_RxBuffer[USART3_RxCounter++] = data;
// 
//             if ('\n' == data)
//             {
//                 if ((USART3_RxCounter > 2) && ('\r' == USART3_RxBuffer[USART3_RxCounter-2]))
//                 {
//                     USART3_RxPackedIncomeFlag = TRUE;
//                     SIM900_RxBufferLength = USART3_RxCounter;
//                     USART3_RxCounter = 0;
//                     for (i=0; i<SIM900_RxBufferLength; i++)
//                     {
//                         SIM900_RxBuffer[i] = USART3_RxBuffer[i];
//                     }
//                     USART3_DisableTimeout();
//                 }
//                 else
//                 {
//                     USART3_RxCounter = 0;
//                     USART3_DisableTimeout();
//                 }
//             }
//             else if (' ' == data)
//             {
//                 if ((USART3_RxCounter >= 2) && ('>' == USART3_RxBuffer[USART3_RxCounter-2]))
//                 {
//                     SIM900_RxBuffer[0] = '>';
//                     SIM900_RxBuffer[1] = ' ';
//                     SIM900_RxBufferLength = 2;
//                     USART3_RxCounter = 0;
//                     USART3_RxPackedIncomeFlag = TRUE;
//                     USART3_DisableTimeout();
//                 }
//             }
        }

        if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
        {   
            /* Write one byte to the transmit data register */
            if (s_TxCounter < s_TxLength)
            {
                USART_SendData(USART1, s_pTxBuffer[s_TxCounter++]);
                s_TxSendingFlag = true;
            }
            else
            {
                s_TxSendingFlag = false;
                USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
            } 
        }
    }

};


void cPc::InitReset()
{
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;

    /* Enable GPIO clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
    /* Enable USART1 Clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 

    /* Configure the NVIC Preemption Priority Bits */  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    /* Enable the USARTy Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Configure USART1 Rx as input floating */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* Configure USART1 Tx as alternate function push-pull */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Configure USART1 */
    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_Init(USART1, &USART_InitStructure);

    /* Enable USARTy Receive and Transmit interrupts */
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    USART_ITConfig(USART1, USART_IT_TXE, DISABLE);

    /* Enable the USART1 */
    USART_Cmd(USART1, ENABLE);

    SendPacked((U8*)"Thong", 5);

//     for( U16 i=0; i<1000; i++ )
//     {
//         s_pTxBuffer[i] = i;
//     }
//     USART_SendData(USART1, s_pTxBuffer[0]);
//     s_TxCounter = 1;
//     s_TxLength = 1000;
//     s_TxSendingFlag = true;
//     USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}


/*******************************************************************************
Function name: SendPacked
Description: Send packed on USART1
Input: None
Output: None
*******************************************************************************/
void cPc::SendPacked(U8 *pData, U16 len)
{
    // wait for old packed is sent
    while(s_TxSendingFlag);
    for( U16 i=0; i<len; i++ )
    {
        s_pTxBuffer[i] = pData[i];
    }
    USART_SendData(USART1, s_pTxBuffer[0]);
    s_TxCounter = 1;
    s_TxLength = len;
    s_TxSendingFlag = true;
    USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}


void cPc::RunOne()
{
    if ( false == s_TxSendingFlag )
    {
        U16 captureValue;
        U16 captureCount = cCapture::GetCaptureValueCount();
        if( 0 == captureCount ) return;

        s_TxLength = 0;
        while( captureCount-- )
        {
            if( true == cCapture::PopCaptureValue( captureValue ) )
            {
                s_pTxBuffer[ s_TxLength++ ] = (U8)(captureValue >> 8);
                s_pTxBuffer[ s_TxLength++ ] = (U8)(captureValue);
            }
        }

        USART_SendData(USART1, s_pTxBuffer[0]);
        s_TxCounter = 1;
        s_TxSendingFlag = true;
        USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
    }
}

